home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / MISC / MAG10.ZIP / FANGLORE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-08-19  |  21.4 KB  |  671 lines

  1. { ************************************************************************** }
  2. { *                                                                        * }
  3. { *                                FANGLORE                                * }
  4. { *                                                                        * }
  5. { *                             BY SPELLCASTER                             * }
  6. { *                                                                        * }
  7. { *                              VERSION 0.30                              * }
  8. { *                                                                        * }
  9. { *                            DATE : 6-8-1996                             * }
  10. { *                                                                        * }
  11. { *                                                                        * }
  12. { *  Developed of 'The Mag', for the 'Designing a Text Adventure'          * }
  13. { *  series of articles...                                                 * }
  14. { *                                                                        * }
  15. { ************************************************************************** }
  16.  
  17. Program FangLore;
  18.  
  19. { ************************************************************************** }
  20. { ************************** Unit definition ******************************* }
  21. { ************************************************************************** }
  22.  
  23. Uses Crt;    { Use CRT for cute text procedures :) }
  24.  
  25. { ************************************************************************** }
  26. { ************************* Constant definition **************************** }
  27. { ************************************************************************** }
  28.  
  29. Const NumberRooms=22;   { Number of rooms in the game }
  30.       NumberObjs=6;     { Number of objects in the game }
  31.  
  32. { ************************************************************************** }
  33. { *************************** Type definition ****************************** }
  34. { ************************************************************************** }
  35.  
  36. Type RoomType=Record
  37.                     Desc:Array[1..10] of String[79];  { Description }
  38.                     North,South,East,West:Byte;       { Exits }
  39.               End;
  40.  
  41.      ParsedType=Array[1..10] Of String;
  42.  
  43.      ObjType=Record
  44.                    Name:String[80];
  45.                    Pos:Byte;
  46.                    Desc:Array[1..5] Of String[80];
  47.              End;
  48.  
  49. { ************************************************************************** }
  50. { ************************* Variable definition **************************** }
  51. { ************************************************************************** }
  52.  
  53. Var Rooms:Array[1..NumberRooms] of RoomType;   { Room data }
  54.     CurrentRoom:Word;                          { Speaks for itself... :) }
  55.     Objects:Array[1..NumberObjs] of ObjType;   { Object data }
  56.     Mask:Boolean;                              { See text for explanation }
  57.  
  58. { ************************************************************************** }
  59. { ************************ Procedure definition **************************** }
  60. { ************************************************************************** }
  61.  
  62. Function FindSpace(S:String;Start:Byte):Byte;     { Finds the first space    }
  63.                                                   { after the indicated char }
  64. Begin
  65.      While (S[Start+1]<>' ') And (Start<Length(S)) Do Inc(Start);
  66.      FindSpace:=Start;
  67. End;
  68.  
  69. Function GetString(S:String;Start,Finish:Byte):String;    { Gets a piece of }
  70.                                                           { a string        }
  71. Var A:Byte;
  72.     Tmp:String;
  73. Begin
  74.      Tmp:='';
  75.      For A:=Start+1 To Finish Do Tmp:=Tmp+S[A];
  76.      GetString:=Tmp;
  77. End;
  78.  
  79. Function Upper(S:String):String;
  80. Var Tmp:String;
  81.     A:Byte;
  82. Begin
  83.      Tmp:='';
  84.      For A:=1 To Length(S) Do Tmp:=Tmp+UpCase(S[A]);
  85.      Upper:=Tmp;
  86. End;
  87.  
  88. Procedure Parse(S:String;Var Parsed:ParsedType);   { Parses a string }
  89. Var ArrayIndex:Byte;
  90.     StringIndex:Byte;
  91.     NextSpace:Byte;
  92. Begin
  93.      ArrayIndex:=1;
  94.      StringIndex:=0;
  95.      NextSpace:=FindSpace(S,StringIndex);
  96.      While (StringIndex<=Length(S)) And (ArrayIndex<11) Do
  97.      Begin
  98.           NextSpace:=FindSpace(S,StringIndex);
  99.           Parsed[ArrayIndex]:=GetString(S,StringIndex,NextSpace);
  100.           StringIndex:=NextSpace+1;
  101.           Inc(ArrayIndex);
  102.      End;
  103. End;
  104.  
  105. Procedure Elimin(Var Parsed:ParsedType;Var Index:Byte);
  106. Var A:Byte;
  107. Begin
  108.      For A:=Index To 9 Do Parsed[A]:=Parsed[A+1];
  109.      Parsed[10]:='';
  110.      Dec(Index);
  111. End;
  112.  
  113. Procedure EliminPrenoms(Var Parsed:ParsedType);
  114. Var A:Byte;
  115. Begin
  116.      For A:=1 To 10 Do
  117.      Begin
  118.           If Parsed[A]='THE' Then Elimin(Parsed,A);
  119.           If Parsed[A]='A' Then Elimin(Parsed,A);
  120.           If Parsed[A]='ON' Then Elimin(Parsed,A);
  121.      End;
  122. End;
  123.  
  124. Procedure ReadRoomData;     { Read from the disk the room data }
  125. Var F:Text;
  126.     A,B:Byte;
  127.     Flag:Boolean;
  128. Begin
  129.      { Prepares the text file for accessing }
  130.      Assign(F,'Room.Dat');
  131.      Reset(F);
  132.      { For every room in the game }
  133.      For A:=1 To NumberRooms Do
  134.      Begin
  135.           { Clear the room's description }
  136.           For B:=1 To 10 Do Rooms[A].Desc[B]:='';
  137.           { Read the description of the room }
  138.           Flag:=True;
  139.           B:=1;
  140.           While Flag Do
  141.           Begin
  142.                Readln(F,Rooms[A].Desc[B]);
  143.                If (B=10) Or (Rooms[A].Desc[B]='*') Then Flag:=False;
  144.                Inc(B);
  145.           End;
  146.           { Read exit data }
  147.           Readln(F,Rooms[A].North);
  148.           Readln(F,Rooms[A].South);
  149.           Readln(F,Rooms[A].East);
  150.           Readln(F,Rooms[A].West);
  151.      End;
  152.      Close(F);
  153. End;
  154.  
  155. Procedure ReadObjData;     { Read from the disk the object data }
  156. Var F:Text;
  157.     A,B:Byte;
  158.     Flag:Boolean;
  159. Begin
  160.      { Prepares the text file for accessing }
  161.      Assign(F,'Obj.Dat');
  162.      Reset(F);
  163.      { For every object in the game }
  164.      For A:=1 To NumberObjs Do
  165.      Begin
  166.           { Read the name of the objects }
  167.           ReadLn(F,Objects[A].Name);
  168.           { Read the initial position of the objects }
  169.           ReadLn(F,Objects[A].Pos);
  170.           { Clear the object's description }
  171.           For B:=1 To 5 Do Objects[A].Desc[B]:='';
  172.           { Read the description of the room }
  173.           Flag:=True;
  174.           B:=1;
  175.           While Flag Do
  176.           Begin
  177.                ReadLn(F,Objects[A].Desc[B]);
  178.                If (B=5) Or (Objects[A].Desc[B]='*') Then Flag:=False;
  179.                Inc(B);
  180.           End;
  181.      End;
  182.      Close(F);
  183. End;
  184.  
  185. Procedure Look(RoomNumber:Word);        { Looks at the room }
  186. Var A:Byte;
  187.     Flag:Boolean;
  188. Begin
  189.      Writeln;
  190.      A:=1;
  191.      TextColor(White);
  192.      While (A<11) And (Rooms[RoomNumber].Desc[A]<>'*') Do
  193.      Begin
  194.           Writeln(Rooms[RoomNumber].Desc[A]);
  195.           Inc(A);
  196.      End;
  197.      Writeln;
  198.      TextColor(Yellow);
  199.      Writeln('Visible exits:');
  200.      If Rooms[RoomNumber].North<>0 Then Write('North      ');
  201.      If Rooms[RoomNumber].South<>0 Then Write('South      ');
  202.      If Rooms[RoomNumber].East<>0 Then Write('East       ');
  203.      If Rooms[RoomNumber].West<>0 Then Write('West       ');
  204.      WriteLn;
  205.      WriteLn;
  206.      TextColor(LightCyan);
  207.      Writeln('Visible objects:');
  208.      Flag:=False;
  209.      For A:=1 To NumberObjs Do If Objects[A].Pos=RoomNumber Then
  210.      Begin
  211.           WriteLn('         ',Objects[A].Name);
  212.           Flag:=True;
  213.      End;
  214.      If Flag=False Then Writeln('          None');
  215.      WriteLn;
  216. End;
  217.  
  218. Procedure Inventory;
  219. Var A:Byte;
  220.     Flag:Boolean;
  221. Begin
  222.      Flag:=False;
  223.      TextColor(LightBlue);
  224.      WriteLn;
  225.      WriteLn('Objects carried:');
  226.      For A:=1 To NumberObjs Do If Objects[A].Pos=0 Then
  227.      Begin
  228.           WriteLn('                ',Objects[A].Name);
  229.           Flag:=True;
  230.      End;
  231.      If Flag=False Then Writeln('                None');
  232.      WriteLn;
  233. End;
  234.  
  235. Procedure Examine(Param:String);
  236. Var Flag:Boolean;
  237.     A,B:Byte;
  238. Begin
  239.      { ***************************************************** }
  240.      { Here we'll include code for things like the oven, etc }
  241.      { ***************************************************** }
  242.      { Search the object in the object list }
  243.      A:=0;
  244.      Flag:=False;
  245.      Repeat
  246.            Inc(A);
  247.            If Upper(Objects[A].Name)=Param Then Flag:=True;
  248.      Until Flag Or (A>NumberObjs);
  249.      If Flag Then
  250.      Begin
  251.           { The object exists }
  252.           { Check if it is in the room or in your possession }
  253.           If (Objects[A].Pos=0) Or (Objects[A].Pos=CurrentRoom) Then
  254.           Begin
  255.                { The object is 'visible'... Write description }
  256.                Writeln;
  257.                B:=1;
  258.                TextColor(Yellow);
  259.                While (B<6) And (Objects[A].Desc[B]<>'*') Do
  260.                Begin
  261.                     Writeln(Objects[A].Desc[B]);
  262.                     Inc(B);
  263.                End;
  264.                Writeln;
  265.           End
  266.           Else
  267.           Begin
  268.                { The object exists, but it's not visible }
  269.                Writeln;
  270.                TextColor(Yellow);
  271.                WriteLn('I can''t see the ',Param,' here...');
  272.                WriteLn;
  273.           End;
  274.      End
  275.      Else
  276.      Begin
  277.           { The specified parameter doesn't represent any existing }
  278.           { object...                                              }
  279.           WriteLn;
  280.           TextColor(Yellow);
  281.           WriteLn('Sorry, but I don''t even know what is a ',Param);
  282.           WriteLn;
  283.      End;
  284. End;
  285.  
  286. Procedure Get(O:String);
  287. Var A:Byte;
  288.     Flag:Boolean;
  289. Begin
  290.      Flag:=False;
  291.      A:=0;
  292.      Repeat
  293.            Inc(A);
  294.            If O=Upper(Objects[A].Name) Then Flag:=True;
  295.      Until (A>NumberObjs) Or (Flag=True);
  296.      If Flag=True Then
  297.      Begin
  298.           { The object exists }
  299.           If Objects[A].Pos=CurrentRoom Then
  300.           Begin
  301.                { The object is in the current room }
  302.                { Get the object }
  303.                Objects[A].Pos:=0;
  304.                TextColor(LightCyan);
  305.                WriteLn;
  306.                WriteLn('You get the ',O);
  307.                WriteLn;
  308.           End
  309.           Else
  310.           Begin
  311.                If Objects[A].Pos=0 Then
  312.                Begin
  313.                     { The object is already in the possession }
  314.                     { of the player...                        }
  315.                     TextColor(LightCyan);
  316.                     WriteLn;
  317.                     WriteLn('You already have the ',O);
  318.                     WriteLn;
  319.                End
  320.                Else
  321.                Begin
  322.                     WriteLn('You don''t see the ',O);
  323.                     WriteLn;
  324.                End;
  325.           End;
  326.      End
  327.      Else
  328.      Begin
  329.           { The object doesn't exist }
  330.           WriteLn;
  331.           TextColor(LightRed);
  332.           Writeln('What are you talking about ?');
  333.           Writeln;
  334.      End;
  335. End;
  336.  
  337. Procedure Drop(O:String);
  338. Var A:Byte;
  339.     Flag:Boolean;
  340. Begin
  341.      Flag:=False;
  342.      A:=0;
  343.      Repeat
  344.            Inc(A);
  345.            If (O=Upper(Objects[A].Name)) And (Objects[A].Pos=0) Then
  346.              Flag:=True;
  347.      Until (A>NumberObjs) Or (Flag=True);
  348.      If Flag=True Then
  349.      Begin
  350.           { The object is in the player's possession }
  351.           Objects[A].Pos:=CurrentRoom;
  352.           TextColor(LightCyan);
  353.           WriteLn;
  354.           WriteLn('You drop the ',O);
  355.           WriteLn;
  356.      End
  357.      Else
  358.      Begin
  359.           { The object doesn't exist or it isn't in the }
  360.           { player's possession... }
  361.           TextColor(LightRed);
  362.           WriteLn;
  363.           WriteLn('You don''t have the ',O);
  364.           WriteLn;
  365.      End;
  366. End;
  367.  
  368. Procedure Use(Arg:ParsedType);
  369. Var A:Byte;
  370.     Flag:Boolean;
  371. Begin
  372.      Flag:=False;
  373.      A:=0;
  374.      Repeat
  375.            Inc(A);
  376.            If (Arg[2]=Upper(Objects[A].Name)) And (Objects[A].Pos=0) Then Flag:=True;
  377.      Until (A>NumberObjs) Or (Flag=True);
  378.      If Flag=True Then
  379.      Begin
  380.           { The object is "usable" }
  381.           Flag:=False;
  382.           { Check if player want to use the shovel }
  383.           If Arg[2]='SHOVEL' Then
  384.           Begin
  385.                Flag:=True;
  386.                { Check if it is used with the door }
  387.                If Arg[3]='DOOR' Then
  388.                Begin
  389.                     { Check if the player is in the proper }
  390.                     { location...                          }
  391.                     If CurrentRoom=20 Then
  392.                     Begin
  393.                          { The player is in the right place }
  394.                          { Open passage between the garden  }
  395.                          { and the mansion...               }
  396.                          Rooms[20].North:=15;
  397.                          TextColor(LightCyan);
  398.                          WriteLn;
  399.                          WriteLn('You knock the door down...');
  400.                          WriteLn;
  401.                     End
  402.                     Else
  403.                     Begin
  404.                          { The player is someplace else }
  405.                          TextColor(LightRed);
  406.                          WriteLn;
  407.                          WriteLn('I don''t see a door...');
  408.                          WriteLn;
  409.                     End;
  410.                End
  411.                Else
  412.                Begin
  413.                     { The player didn't used the shovel with }
  414.                     { the door...                            }
  415.                     TextColor(LightRed);
  416.                     WriteLn;
  417.                     WriteLn('Use it with what ?!');
  418.                     WriteLn;
  419.                End;
  420.           End;
  421.           If Arg[2]='SWORD' Then
  422.           Begin
  423.                Flag:=True;
  424.                { I'll include the code here in a future  }
  425.                { issue, when I'll talk about monsters... }
  426.           End;
  427.      End;
  428.      If Flag=False Then
  429.      Begin
  430.           { No "legal" objects were used }
  431.           TextColor(LightRed);
  432.           WriteLn;
  433.           WriteLn('Can''t use that...');
  434.           WriteLn;
  435.      End;
  436. End;
  437.  
  438. Procedure Init;      { Initializes game data }
  439. Begin
  440.      ReadRoomData;
  441.      ReadObjData;
  442.      CurrentRoom:=22;
  443.      Mask:=False;
  444.      TextColor(LightGray);
  445.      TextBackground(Black);
  446.      Clrscr;
  447. End;
  448.  
  449. Procedure Play;      { Playing the game }
  450. Var ExitFlag:Boolean;
  451.     Valid:Boolean;
  452.     Command:String;
  453.     Parsed:ParsedType;
  454.     A,D:Byte;
  455.     C:Char;
  456.     E:String;
  457. Begin
  458.      ExitFlag:=False;
  459.      Look(CurrentRoom);
  460.      Repeat
  461.            Valid:=False;
  462.            TextColor(White);
  463.            Writeln('What is thy bidding, master ?');
  464.            TextColor(LightGreen);
  465.            Readln(Command);
  466.            { Clear the array }
  467.            For A:=1 To 10 Do Parsed[A]:='';
  468.            Parse(Command,Parsed);
  469.            { Convert to uppercase }
  470.            For A:=1 To 10 Do Parsed[A]:=Upper(Parsed[A]);
  471.            { Eliminate prenoms }
  472.            EliminPrenoms(Parsed);
  473.            { Execute comands }
  474.            If Parsed[1]='LOOK' Then
  475.            Begin
  476.                 Valid:=True;
  477.                 Look(CurrentRoom);
  478.            End;
  479.            If Parsed[1]='INVENTORY' Then
  480.            Begin
  481.                 Valid:=True;
  482.                 Inventory;
  483.            End;
  484.            If Parsed[1]='EXAMINE' Then
  485.            Begin
  486.                 Valid:=True;
  487.                 { Join the words again }
  488.                 D:=3;
  489.                 E:=Parsed[2];
  490.                 While Parsed[D]<>'' Do
  491.                 Begin
  492.                      E:=E+' '+Parsed[D];
  493.                      Inc(D);
  494.                 End;
  495.                 Examine(E);
  496.            End;
  497.            If Parsed[1]='GET' Then
  498.            Begin
  499.                 Valid:=True;
  500.                 { Join the words again }
  501.                 D:=3;
  502.                 E:=Parsed[2];
  503.                 While Parsed[D]<>'' Do
  504.                 Begin
  505.                      E:=E+' '+Parsed[D];
  506.                      Inc(D);
  507.                 End;
  508.                 Get(E);
  509.            End;
  510.            If Parsed[1]='DROP' Then
  511.            Begin
  512.                 Valid:=True;
  513.                 { Join the words again }
  514.                 D:=3;
  515.                 E:=Parsed[2];
  516.                 While Parsed[D]<>'' Do
  517.                 Begin
  518.                      E:=E+' '+Parsed[D];
  519.                      Inc(D);
  520.                 End;
  521.                 Drop(E);
  522.            End;
  523.            If Parsed[1]='WEAR' Then
  524.            Begin
  525.                 { Join the words again }
  526.                 D:=3;
  527.                 E:=Parsed[2];
  528.                 While Parsed[D]<>'' Do
  529.                 Begin
  530.                      E:=E+' '+Parsed[D];
  531.                      Inc(D);
  532.                 End;
  533.                 If E='GAS MASK' Then
  534.                 Begin
  535.                      { Check if the player has the gas mask     }
  536.                      { We know that the mask is object number 2 }
  537.                      Valid:=True;
  538.                      If Objects[2].Pos=0 Then
  539.                      Begin
  540.                           Mask:=True;
  541.                           TextColor(LightCyan);
  542.                           WriteLn;
  543.                           WriteLn('You wear the gas mask...');
  544.                           WriteLn;
  545.                      End
  546.                      Else
  547.                      Begin
  548.                           TextColor(LightRed);
  549.                           WriteLn;
  550.                           WriteLn('You don''t have the gas mask.');
  551.                           WriteLn;
  552.                      End;
  553.                 End;
  554.            End;
  555.            If Parsed[1]='USE' Then
  556.            Begin
  557.                 Valid:=True;
  558.                 Use(Parsed);
  559.            End;
  560.            If (Parsed[1]='N') Or (Parsed[1]='NORTH') Then
  561.            Begin
  562.                 If Rooms[CurrentRoom].North=0 Then
  563.                 Begin
  564.                      TextColor(LightRed);
  565.                      Writeln;
  566.                      Writeln('Sorry, oh Great Lord, but I can''t go that way !');
  567.                      Writeln;
  568.                 End
  569.                 Else
  570.                 Begin
  571.                      TextColor(LightRed);
  572.                      Writeln;
  573.                      Writeln('You go north...');
  574.                      CurrentRoom:=Rooms[CurrentRoom].North;
  575.                      Writeln;
  576.                      Look(CurrentRoom);
  577.                 End;
  578.                 Valid:=True;
  579.            End;
  580.            If (Parsed[1]='S') Or (Parsed[1]='SOUTH') Then
  581.            Begin
  582.                 If Rooms[CurrentRoom].South=0 Then
  583.                 Begin
  584.                      TextColor(LightRed);
  585.                      Writeln;
  586.                      Writeln('Sorry, oh Great Lord, but I can''t go that way !');
  587.                      Writeln;
  588.                 End
  589.                 Else
  590.                 Begin
  591.                      TextColor(LightRed);
  592.                      Writeln;
  593.                      Writeln('You go south...');
  594.                      CurrentRoom:=Rooms[CurrentRoom].South;
  595.                      Writeln;
  596.                      Look(CurrentRoom);
  597.                 End;
  598.                 Valid:=True;
  599.            End;
  600.            If (Parsed[1]='E') Or (Parsed[1]='EAST') Then
  601.            Begin
  602.                 If Rooms[CurrentRoom].East=0 Then
  603.                 Begin
  604.                      TextColor(LightRed);
  605.                      Writeln;
  606.                      Writeln('Sorry, oh Great Lord, but I can''t go that way !');
  607.                      Writeln;
  608.                 End
  609.                 Else
  610.                 Begin
  611.                      TextColor(LightRed);
  612.                      Writeln;
  613.                      Writeln('You go east...');
  614.                      CurrentRoom:=Rooms[CurrentRoom].East;
  615.                      Writeln;
  616.                      Look(CurrentRoom);
  617.                 End;
  618.                 Valid:=True;
  619.            End;
  620.            If (Parsed[1]='W') Or (Parsed[1]='WEST') Then
  621.            Begin
  622.                 If Rooms[CurrentRoom].West=0 Then
  623.                 Begin
  624.                      TextColor(LightRed);
  625.                      Writeln;
  626.                      Writeln('Sorry, oh Great Lord, but I can''t go that way !');
  627.                      Writeln;
  628.                 End
  629.                 Else
  630.                 Begin
  631.                      TextColor(LightRed);
  632.                      Writeln;
  633.                      Writeln('You go west...');
  634.                      CurrentRoom:=Rooms[CurrentRoom].West;
  635.                      Writeln;
  636.                      Look(CurrentRoom);
  637.                 End;
  638.                 Valid:=True;
  639.            End;
  640.            If Parsed[1]='QUIT' Then
  641.            Begin
  642.                 Valid:=True;
  643.                 TextColor(LightMagenta);
  644.                 Writeln;
  645.                 Writeln('Are you sure you want to quit FangLore (Y/N) ?');
  646.                 C:=ReadKey;
  647.                 If UpCase(C)='Y' Then ExitFlag:=True;
  648.                 Writeln;
  649.            End;
  650.            If Not Valid Then
  651.            Begin
  652.                 Writeln;
  653.                 TextColor(LightRed);
  654.                 If Random(100)>50 Then
  655.                    Writeln('Sorry mylord, by thy bidding can''t be obbeyed...')
  656.                 Else
  657.                    Writeln('What ?! How the hell am I supposed to do that ??');
  658.                 Writeln;
  659.            End;
  660.      Until ExitFlag;
  661. End;
  662.  
  663. { ************************************************************************** }
  664. { **************************** Main  Program ******************************* }
  665. { ************************************************************************** }
  666.  
  667. Begin
  668.      Init;
  669.      Play;
  670. End.
  671.